from sqlalchemy import Column, Integer, String, DateTime, Text, Boolean, JSON
from sqlalchemy.sql import func
from sqlalchemy.orm import relationship
from app.database.connection import Base
from datetime import datetime, timezone
from typing import Optional, Dict, Any

class User(Base):
    """用户模型"""
    
    __tablename__ = "users"
    
    # 基础字段
    id = Column(Integer, primary_key=True, index=True, comment="用户ID")
    username = Column(String(50), unique=True, index=True, nullable=False, comment="用户名")
    email = Column(String(100), unique=True, index=True, nullable=False, comment="邮箱")
    hashed_password = Column(String(255), nullable=False, comment="加密密码")
    
    # 个人信息
    nickname = Column(String(50), nullable=True, comment="昵称")
    avatar_url = Column(String(255), nullable=True, comment="头像URL")
    bio = Column(Text, nullable=True, comment="个人简介")
    
    # 状态字段
    is_active = Column(Boolean, default=True, comment="是否激活")
    is_verified = Column(Boolean, default=False, comment="是否验证邮箱")
    is_premium = Column(Boolean, default=False, comment="是否高级用户")
    
    # 时间字段
    created_at = Column(DateTime(timezone=True), server_default=func.now(), comment="创建时间")
    updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), comment="更新时间")
    last_login_at = Column(DateTime(timezone=True), nullable=True, comment="最后登录时间")
    
    # 用户偏好设置
    preferences = Column(JSON, nullable=True, comment="用户偏好设置")
    
    def __repr__(self):
        """打印格式"""
        return f"<User(id={self.id}, username='{self.username}', email='{self.email}')>"
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典格式，便于直接序列化为 JSON 返回给前端"""
        return {
            "id": self.id,
            "username": self.username,
            "email": self.email,
            "nickname": self.nickname,
            "avatar_url": self.avatar_url,
            "bio": self.bio,
            "is_active": self.is_active,
            "is_verified": self.is_verified,
            "is_premium": self.is_premium,
            "created_at": self.created_at.isoformat() if self.created_at else None,
            "updated_at": self.updated_at.isoformat() if self.updated_at else None,
            "last_login_at": self.last_login_at.isoformat() if self.last_login_at else None,
            "preferences": self.preferences or {}
        }
    
    def update_last_login(self):
        """更新最后登录时间"""
        self.last_login_at = datetime.now(timezone.utc)
    
    def set_preferences(self, preferences: Dict[str, Any]):
        """设置用户偏好"""
        if self.preferences is None:
            self.preferences = {}
        self.preferences.update(preferences)
    
    def get_preference(self, key: str, default: Any = None) -> Any:
        """获取用户偏好设置"""
        if self.preferences is None:
            return default
        return self.preferences.get(key, default)

class UserProfile(Base):
    """用户画像模型"""
    
    __tablename__ = "user_profiles"
    
    # 基础字段
    id = Column(Integer, primary_key=True, index=True, comment="画像ID")
    user_id = Column(Integer, index=True, nullable=False, comment="用户ID")
    
    # 基本信息
    age_group = Column(String(20), nullable=True, comment="年龄段")
    gender = Column(String(10), nullable=True, comment="性别")
    location = Column(String(100), nullable=True, comment="地理位置")
    
    # 观影偏好
    favorite_genres = Column(JSON, nullable=True, comment="喜欢的类型")
    favorite_actors = Column(JSON, nullable=True, comment="喜欢的演员")
    favorite_directors = Column(JSON, nullable=True, comment="喜欢的导演")
    
    # 情感偏好
    emotional_preferences = Column(JSON, nullable=True, comment="情感偏好")
    mood_history = Column(JSON, nullable=True, comment="情绪历史")
    
    # 行为数据
    viewing_history = Column(JSON, nullable=True, comment="观影历史")
    rating_history = Column(JSON, nullable=True, comment="评分历史")
    search_history = Column(JSON, nullable=True, comment="搜索历史")
    
    # 推荐相关
    recommendation_feedback = Column(JSON, nullable=True, comment="推荐反馈")
    interaction_patterns = Column(JSON, nullable=True, comment="交互模式")
    
    # 时间字段
    created_at = Column(DateTime(timezone=True), server_default=func.now(), comment="创建时间")
    updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), comment="更新时间")
    
    def __repr__(self):
        """打印格式"""
        return f"<UserProfile(id={self.id}, user_id={self.user_id})>"
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典格式"""
        return {
            "id": self.id,
            "user_id": self.user_id,
            "age_group": self.age_group,
            "gender": self.gender,
            "location": self.location,
            "favorite_genres": self.favorite_genres or [],
            "favorite_actors": self.favorite_actors or [],
            "favorite_directors": self.favorite_directors or [],
            "emotional_preferences": self.emotional_preferences or {},
            "mood_history": self.mood_history or [],
            "viewing_history": self.viewing_history or [],
            "rating_history": self.rating_history or [],
            "search_history": self.search_history or [],
            "recommendation_feedback": self.recommendation_feedback or {},
            "interaction_patterns": self.interaction_patterns or {},
            "created_at": self.created_at.isoformat() if self.created_at else None,
            "updated_at": self.updated_at.isoformat() if self.updated_at else None
        }
    
    def add_viewing_record(self, movie_data: Dict[str, Any]):
        """添加观影记录"""
        if self.viewing_history is None:
            self.viewing_history = []
        
        record = {
            "movie_id": movie_data.get("id"),
            "title": movie_data.get("title"),
            "timestamp": datetime.now(datetime.timezone.utc).isoformat(),
            "rating": movie_data.get("user_rating"),
            "genres": movie_data.get("genres", [])
        }
        
        self.viewing_history.append(record)
        
        # 保持最近100条记录
        if len(self.viewing_history) > 100:
            self.viewing_history = self.viewing_history[-100:]
    
    def update_emotional_preference(self, emotion: str, weight: float):
        """更新情感偏好"""
        if self.emotional_preferences is None:
            self.emotional_preferences = {}
        
        current_weight = self.emotional_preferences.get(emotion, 0.0)
        # 使用加权平均更新
        new_weight = (current_weight * 0.8) + (weight * 0.2)
        self.emotional_preferences[emotion] = new_weight
    
    def get_top_genres(self, limit: int = 5) -> list:
        """获取最喜欢的电影类型"""
        if not self.favorite_genres:
            return []
        
        # 按权重排序
        sorted_genres = sorted(
            self.favorite_genres.items(),
            key=lambda x: x[1],
            reverse=True
        )
        return [genre for genre, _ in sorted_genres[:limit]]